package com.zhentao.utils;

import java.time.LocalDateTime;
import java.time.ZoneOffset;

public class SnowflakeIdGenerator {
    // 基础配置（Java 8+）
    private static final long EPOCH = 1288834974657L; // 2010-11-04 00:00:00 UTC
    private static final int DATACENTER_ID_BITS = 5;
    private static final int WORKER_ID_BITS = 5;
    private static final int SEQUENCE_BITS = 12;
    // 位运算掩码
    private static final long DATACENTER_ID_MASK = (1L << DATACENTER_ID_BITS) - 1;
    private static final long WORKER_ID_MASK = (1L << WORKER_ID_BITS) - 1;
    private static final long SEQUENCE_MASK = (1L << SEQUENCE_BITS) - 1;

    // 位移偏移量
    private static final int WORKER_ID_SHIFT = SEQUENCE_BITS;
    private static final int DATACENTER_ID_SHIFT = SEQUENCE_BITS + WORKER_ID_BITS;
    private static final int TIMESTAMP_SHIFT = SEQUENCE_BITS + WORKER_ID_BITS + DATACENTER_ID_BITS;

    private final long datacenterId;
    private final long workerId;
    private long sequence = 0L;
    private long lastTimestamp = -1L;

    private final Object lock = new Object();

    public SnowflakeIdGenerator(long datacenterId, long workerId) {
        if ((datacenterId & DATACENTER_ID_MASK) != datacenterId) {
            throw new IllegalArgumentException("DataCenter ID 必须在 0-31 之间");
        }
        if ((workerId & WORKER_ID_MASK) != workerId) {
            throw new IllegalArgumentException("Worker ID 必须在 0-31 之间");
        }
        this.datacenterId = datacenterId;
        this.workerId = workerId;
    }

    public synchronized long nextId() {
        long currentTimestamp = timeGen();

        if (currentTimestamp < lastTimestamp) {
            throw new IllegalStateException(
                    String.format("时钟回退 %d 毫秒，禁止生成ID（上次: %d，当前: %d）",
                            lastTimestamp - currentTimestamp, lastTimestamp, currentTimestamp));
        }

        if (currentTimestamp == lastTimestamp) {
            sequence = (sequence + 1) & SEQUENCE_MASK;
            if (sequence == 0) {
                currentTimestamp = waitNextMillis(lastTimestamp);
            }
        } else {
            sequence = 0;
        }

        lastTimestamp = currentTimestamp;

        return ((currentTimestamp - EPOCH) << TIMESTAMP_SHIFT) |
                (datacenterId << DATACENTER_ID_SHIFT) |
                (workerId << WORKER_ID_SHIFT) |
                sequence;
    }

    private long waitNextMillis(long lastTimestamp) {
        long timestamp = timeGen();
        while (timestamp <= lastTimestamp) {
            timestamp = System.currentTimeMillis(); // 改用更可靠的时间源
        }
        return timestamp;
    }

    private long timeGen() {
        return System.currentTimeMillis();
    }

    // 添加 parseId 方法
    public static SnowflakeMeta parseId(long snowflakeId) {
        long sequence = snowflakeId & SEQUENCE_MASK;
        long workerId = (snowflakeId >> WORKER_ID_SHIFT) & WORKER_ID_MASK;
        long datacenterId = (snowflakeId >> DATACENTER_ID_SHIFT) & DATACENTER_ID_MASK;
        long timestamp = (snowflakeId >> TIMESTAMP_SHIFT) + EPOCH;

        return new SnowflakeMeta(
                timestamp,
                datacenterId,
                workerId,
                sequence,
                LocalDateTime.ofEpochSecond(timestamp / 1000, 0, ZoneOffset.ofHours(8))
        );
    }
    public static Long getSnowId(){
        SnowflakeIdGenerator generator=new SnowflakeIdGenerator(1,1);
        long id = generator.nextId();
        SnowflakeMeta meta=SnowflakeIdGenerator.parseId(id);
        return id;
    }
    // ---------------- 修复：添加完整的getter方法 ----------------
    public static class SnowflakeMeta {
        private final long timestamp;
        private final long datacenterId;
        private final long workerId;
        private final long sequence;
        private final LocalDateTime dateTime;

        public SnowflakeMeta(long timestamp, long datacenterId, long workerId, long sequence, LocalDateTime dateTime) {
            this.timestamp = timestamp;
            this.datacenterId = datacenterId;
            this.workerId = workerId;
            this.sequence = sequence;
            this.dateTime = dateTime;
        }

        // 显式定义getter（修复爆红）
        public long getTimestamp() {
            return timestamp;
        }

        public long getDatacenterId() {
            return datacenterId;
        }

        public long getWorkerId() {
            return workerId;
        }

        public long getSequence() {
            return sequence;
        }

        public LocalDateTime getDateTime() {
            return dateTime;
        }
    }
}
